﻿using System;
using System.Collections.Generic;
using System.Text;
using PersistenceObject.Common;
using System.Data;
using System.Reflection;

namespace PersistenceObject.Framework
{
    public static class CommonHelper
    {
        /// <summary>
        /// 提取数据集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <param name="t"></param>
        public static List<T> DataReaderToTList<T>(IDataReader dr) where T : class
        {
            List<T> list = new List<T>();

            ObjectMap om = ObjectMapContainer.Instance.Get(typeof(T));

            Dictionary<string, int> dbFields = new Dictionary<string, int>();
            for (int index = 0; index < dr.FieldCount; index++)
            {
                string fieldName = dr.GetName(index);
                try
                {
                    dbFields.Add(fieldName.ToLower(), index);
                }
                catch { }
            }

            while (dr.Read())
            {
                T t = om.GetObject<T>();

                foreach (ColumnInfo info in om.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));

                        om.SetValueEmit(info.PropertyInfo, t, dr.GetValue(dbFields[cn]));

                    }
                }

                list.Add(t);

            }
            return list;
        }

        public static T DataReaderToT<T>(IDataReader dr) where T : class
        {
            if (dr.Read())
            {
                ObjectMap om = ObjectMapContainer.Instance.Get(typeof(T));
                T t = om.GetObject<T>();
                Dictionary<string, int> dbFields = new Dictionary<string, int>();
                for (int index = 0; index < dr.FieldCount; index++)
                {

                    string fieldName = dr.GetName(index);
                    try
                    {
                        dbFields.Add(fieldName.ToLower(), index);
                    }
                    catch { }
                }

                foreach (ColumnInfo info in om.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {

                        om.SetValueEmit(info.PropertyInfo, t, dr.GetValue(dbFields[cn]));

                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                    }
                }

                return t;
            }

            return null;

        }

        public static object GetPropertyValue<T>(ObjectMap om, PropertyInfo propertyInfo, T t) where T : class
        {
            return om.GetValueEmit(propertyInfo, t);
        }

        /// <summary>
        /// 两个类型结果集的转换提取
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static List<Combined<T1, T2>> DataReaderToTList<T1, T2>(IDataReader dr)
            where T1 : class
            where T2 : class
        {
            List<Combined<T1, T2>> list = new List<Combined<T1, T2>>();

            ObjectMap om1 = ObjectMapContainer.Instance.Get(typeof(T1));
            ObjectMap om2 = ObjectMapContainer.Instance.Get(typeof(T2));

            Dictionary<string, int> dbFields = new Dictionary<string, int>();
            for (int index = 0; index < dr.FieldCount; index++)
            {
                string fieldName = dr.GetName(index);
                try
                {
                    dbFields.Add(fieldName.ToLower(), index);
                }
                catch { }
            }

            while (dr.Read())
            {
                T1 t1 = om1.GetObject<T1>();
                T2 t2 = om2.GetObject<T2>();

                foreach (ColumnInfo info in om1.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om1.SetValueEmit(info.PropertyInfo, t1, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om2.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t2, dr.GetValue(dbFields[cn]));
                    }
                }

                list.Add(new Combined<T1, T2>(t1, t2));

            }
            return list;
        }

        /// <summary>
        /// 两个结果集的提取
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static Combined<T1, T2> DataReaderToT<T1, T2>(IDataReader dr)
            where T1 : class
            where T2 : class
        {
            if (dr.Read())
            {
                ObjectMap om1 = ObjectMapContainer.Instance.Get(typeof(T1));
                ObjectMap om2 = ObjectMapContainer.Instance.Get(typeof(T2));

                T1 t1 = om1.GetObject<T1>();
                T2 t2 = om2.GetObject<T2>();

                Dictionary<string, int> dbFields = new Dictionary<string, int>();
                for (int index = 0; index < dr.FieldCount; index++)
                {

                    string fieldName = dr.GetName(index);
                    try
                    {
                        dbFields.Add(fieldName.ToLower(), index);
                    }
                    catch { }
                }

                foreach (ColumnInfo info in om1.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om1.SetValueEmit(info.PropertyInfo, t1, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om2.Columns)
                {
                    string cn = info.ColumnName.ToLower();
                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t2, dr.GetValue(dbFields[cn]));
                    }
                }

                return new Combined<T1, T2>(t1, t2);
            }

            return null;

        }

        /// <summary>
        /// 两个类型结果集的转换提取
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static List<Combined<T1, T2, T3>> DataReaderToTList<T1, T2, T3>(IDataReader dr)
            where T1 : class
            where T2 : class
            where T3 : class
        {
            List<Combined<T1, T2, T3>> list = new List<Combined<T1, T2, T3>>();

            ObjectMap om1 = ObjectMapContainer.Instance.Get(typeof(T1));
            ObjectMap om2 = ObjectMapContainer.Instance.Get(typeof(T2));
            ObjectMap om3 = ObjectMapContainer.Instance.Get(typeof(T3));

            Dictionary<string, int> dbFields = new Dictionary<string, int>();
            for (int index = 0; index < dr.FieldCount; index++)
            {
                string fieldName = dr.GetName(index);
                try
                {
                    dbFields.Add(fieldName.ToLower(), index);
                }
                catch { }
            }

            while (dr.Read())
            {
                T1 t1 = om1.GetObject<T1>();
                T2 t2 = om2.GetObject<T2>();
                T3 t3 = om3.GetObject<T3>();

                foreach (ColumnInfo info in om1.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om1.SetValueEmit(info.PropertyInfo, t1, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om2.Columns)
                {
                    string cn = info.ColumnName.ToLower();

                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t2, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om3.Columns)
                {
                    string cn = info.ColumnName.ToLower();
                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t3, dr.GetValue(dbFields[cn]));
                    }
                }

                list.Add(new Combined<T1, T2, T3>(t1, t2, t3));

            }
            return list;
        }

        /// <summary>
        /// 两个结果集的提取
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="dr"></param>
        /// <returns></returns>
        public static Combined<T1, T2, T3> DataReaderToT<T1, T2, T3>(IDataReader dr)
            where T1 : class
            where T2 : class
            where T3 : class
        {
            if (dr.Read())
            {
                ObjectMap om1 = ObjectMapContainer.Instance.Get(typeof(T1));
                ObjectMap om2 = ObjectMapContainer.Instance.Get(typeof(T2));
                ObjectMap om3 = ObjectMapContainer.Instance.Get(typeof(T3));

                T1 t1 = om1.GetObject<T1>();
                T2 t2 = om2.GetObject<T2>();
                T3 t3 = om3.GetObject<T3>();

                Dictionary<string, int> dbFields = new Dictionary<string, int>();
                for (int index = 0; index < dr.FieldCount; index++)
                {

                    string fieldName = dr.GetName(index);
                    try
                    {
                        dbFields.Add(fieldName.ToLower(), index);
                    }
                    catch { }
                }

                foreach (ColumnInfo info in om1.Columns)
                {
                    string cn = info.ColumnName.ToLower();
                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om1.SetValueEmit(info.PropertyInfo, t1, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om2.Columns)
                {
                    string cn = info.ColumnName.ToLower();
                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t2, dr.GetValue(dbFields[cn]));
                    }
                }

                foreach (ColumnInfo info in om3.Columns)
                {
                    string cn = info.ColumnName.ToLower();
                    if (!dbFields.ContainsKey(cn)) continue;

                    if (!dr.IsDBNull(dbFields[cn]))
                    {
                        //TypeHelper.Instance.SetPropertyValue<T>(t, info.PropertyName, dr.GetValue(dbFields[info.ColumnName]));
                        om2.SetValueEmit(info.PropertyInfo, t3, dr.GetValue(dbFields[cn]));
                    }
                }

                return new Combined<T1, T2, T3>(t1, t2, t3);
            }

            return null;

        }

    }
}
